#pragma once
#include "json.hpp"
#include "public.hpp"
#include "usermodel.hpp"
#include "offlineMsgModel.hpp"
#include "friendmodel.hpp"
#include "groupmodel.hpp"
#include "redis.hpp"
#include <muduo/net/TcpConnection.h>
#include <unordered_map>
#include <functional>
#include <mutex>

using namespace muduo;
using namespace muduo::net;
using json = nlohmann::json;

using MsgHandler = std::function<void(const TcpConnectionPtr& pt, json& js, Timestamp)>;

/////////////////////////////////////////////////////////////////////////////////////////////
/*

    ChatService是一个处理聊天服务器业务的类
    
*/
class ChatService
{
private:
    ChatService();
    ChatService(const ChatService&) = delete;
    ChatService& operator=(const ChatService&) = delete;  
    void Init();
public:
    /*············································

                获取单例对象的接口函数
    
    ············································*/
    static ChatService* GetInstance();
    /*············································

                获取消息对应的处理方法
    
    ············································*/
    MsgHandler GetHandler(int msgid);
    /*············································

                    客户端异常退出
    
    ············································*/
    void ClientCloseException(const TcpConnectionPtr&);
    /*············································

                服务器异常后业务重置的方法
    
    ············································*/
    void Reset();
    /*············································

                    处理登录业务
    
    ············································*/
    void Login(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    处理注册业务
    
    ············································*/
    void Reg(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    处理私聊业务
    
    ············································*/
    void OneChat(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    添加好友业务
    
    ············································*/
    void AddFriend(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    创建群组业务
    
    ············································*/
    void CreateGroup(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    加入群组业务
    
    ············································*/
    void AddGroup(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    群组聊天业务
    
    ············································*/
    void GroupChat(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

                    处理注销业务
    
    ············································*/
    void LoginOut(const TcpConnectionPtr& pt, json& js, Timestamp time);
    /*············································

            从redis消息队列中获取订阅的消息
    
    ············································*/
    void HandleRedisSubscribeMessage(int, std::string);
private:
    // 存储消息id和其对应业务的处理方法
    std::unordered_map<int, MsgHandler> _msgHandlerMap;

    //  存储用户连接信息
    std::unordered_map<int, TcpConnectionPtr> _userConnMap;
    std::mutex _connMapMutex;

    UserModel _userModel;
    OfflineMsgModel _offlineMsgModel;
    FriendModel _friendModel;
    GroupModel _groupModel;

    // redis操作对象
    Redis _redis;
};
